import path from "path";
import webpack, { Chunk, EntryObject } from "webpack";
import TerserWebpackPlugin from "terser-webpack-plugin";
import { VueLoaderPlugin } from "vue-loader";
import HtmlWebpackPlugin from "html-webpack-plugin";

const config: webpack.Configuration | webpack.WebpackOptionsNormalized = {
  mode: process.env.NODE_ENV === "development" ? "development" : "production",
  entry: {
    index: "./src/main.ts",
    "index.min": "./src/main.ts",
    "index.min.pure": "./src/main.ts",
    model: "./src/model/index.ts",
    container: "./src/components/container/index.ts",
  },
  output: {
    publicPath: '',
    path: path.resolve(__dirname, "dist"),
    assetModuleFilename: "assets/[name][ext][query]",
    filename: "[name].js",
    chunkFilename: "[name].js",
    library: "RdjVueComponents",
    libraryTarget: "umd",
    globalObject: "this",
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserWebpackPlugin({
        include: /min/,
      }),
    ],
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ["vue-loader"],
      },
      {
        test: /\.(png|jpg|gif)$/i,
        type: "asset/resource",
      },
      {
        test: /\.(scss|css)$/,
        use: [
          "vue-style-loader",
          {
            loader: "css-loader",
            options: {
              importLoaders: 2,
            },
          },
          {
            loader: "postcss-loader",
          },
          "sass-loader",
        ],
      },
      {
        test: /\.ts$/,
        loader: "ts-loader",
        options: { appendTsSuffixTo: [/\.vue$/] },
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        options: {
          rootMode: "upward",
          presets: ["@vue/app", "@babel/env"],
          "env": {
            "test": {
              "presets": [["env", { "targets": { "node": "current" } }]]
            }
          }
        },
      },
    ],
  },
  resolve: {
    extensions: [".ts", ".js", ".vue"],
    alias: {
      vue$: "vue/dist/vue.min.js",
    },
  },
  plugins: [
    new VueLoaderPlugin() as any,
  ],
  devServer: {
    static: [
      {
        directory: path.join(__dirname, "src"),
        publicPath: "/",
      },
      {
        directory: path.join(__dirname, "dev"),
        publicPath: "/",
      },
    ],
    port: 8000,
    compress: true, //压缩
    open: true, //自动打开浏览器 url 地址
    hot: true, //热重载，热更新
  },
  devtool:
    process.env.NODE_ENV === "development" ? "eval-source-map" : "source-map",
};

if (process.env.NODE_ENV === "production") {
  // 正式打包 生成版权信息等
  (config.optimization as any)["splitChunks"] = {
    // 表示选择哪些 chunks 进行分割，可选值有：async，initial和all
    chunks: (chunk: Chunk) => {
      return chunk.name === "index.min.pure";
    },
    // 表示新分离出的chunk必须大于等于minSize，默认为30000，约30kb。
    minSize: 30000,
    // 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
    minChunks: 1,
    // 表示按需加载文件时，并行请求的最大数目。默认为5。
    maxAsyncRequests: 5,
    // 表示加载入口文件时，并行请求的最大数目。默认为3。
    maxInitialRequests: 3,
    // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
    automaticNameDelimiter: "~",
    // 设置chunk的文件名。默认为false。当为false时，splitChunks基于chunk和cacheGroups的key自动命名。
    // name: false,
    // cacheGroups 下可以可以配置多个组，每个组根据test设置条件，符合test条件的模块，就分配到该组。模块可以被多个组引用，但最终会根据priority来决定打包到哪个组中。默认将所有来自 node_modules目录的模块打包至vendors组，将两个以上的chunk所共享的模块打包至default组。
    cacheGroups: {
      vue: {
        name: "vue",
        filename: '[name].min.js',
        test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
        priority: -5,
      },
      // vuex: {
      //   name: 'vuex',
      //   test: /[\\/]node_modules[\\/]vuex[\\/]/,
      //   priority: -10
      // },
      // 'vue-router': {
      //   name: 'vue-router',
      //   test: /[\\/]node_modules[\\/]vue-router[\\/]/,
      //   priority: -10
      // },
      // 'element-ui': {
      //   name: 'element-ui',
      //   test: /[\\/]node_modules[\\/]element-ui[\\/]/,
      //   priority: -10
      // },
      vendors: {
        name: 'vendors',
        filename: '[name].min.js',
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
      },
      default: {
        filename: '[name].min.js',
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true,
      },
    },
  };
  const pkg = require("./package");
  const banner = [
    `${pkg.name} v${process.env.VERSION || pkg.version}`,
    `(c) 2021-${new Date().getFullYear()} ${pkg.author.name}`,
    `${pkg.license} License`,
  ].join("\n");
  if (config.plugins) config.plugins.push(new webpack.BannerPlugin(banner));
} else {
  // 开发环境
  (config.entry as EntryObject)["devMain"] = "./dev/main.ts";
  if (config.plugins)
    config.plugins.push(
      new HtmlWebpackPlugin({
        filename: "index.html",
        template: "./dev/dev_template.html",
        inject: false,
      })
    );
}
console.log("config", config);

export default config;
